<script setup lang="ts">
import {
  defineAsyncComponent,
  ref,
  shallowRef,
  type Component,
  toRefs,
} from "vue";
import { ElEmpty } from "element-plus";
const pros = withDefaults(
  defineProps<{
    title: string;
    footer?: boolean;
    path: string;
  }>(),
  {
    footer: true,
  }
);
const emits = defineEmits<{
  (e: "submit"): void;
  (e: "cancel"): void;
  (e: "error"): void;
  (e: "success"): void;
}>();
const Title = ref(pros.title);
const Footer = ref(pros.footer);
const Path = ref(pros.path);
const instance = ref<{
  submit: () => void;
  cancel: () => void;
} | null>(null);
const loading = ref(false);
const dialogVisible = ref(false);
const component = shallowRef<Component>();
const submit = () => {
  loading.value = true;
  instance.value?.submit();
  emits("submit");
};
const cancel = () => {
  emits("cancel");
};
const success = () => {
  loading.value = false;
  dialogVisible.value = false;
  emits("success");
};
const error = () => {
  loading.value = false;
  dialogVisible.value = true;
  emits("error");
};
const modules = import.meta.glob<Component>("../../views/**/**.vue");
const open = (title?: string, path?: string) => {
  Title.value = title || pros.title;
  Path.value = path || pros.path;
  dialogVisible.value = true;
  component.value = defineAsyncComponent({
    loader:
      modules[/* @vite-ignore */ `../..${Path.value}`] ||
      (() => Promise.resolve(ElEmpty)),
  });
};

defineExpose({
  open,
});
</script>
<template>
  <!-- 用户表单对话框 -->
  <el-dialog
    v-model="dialogVisible"
    :title="title"
    width="500px"
    destroy-on-close
  >
    <component
      ref="instance"
      @submit="submit"
      @cancel="cancel"
      @success="success"
      @error="error"
      :is="component"
    />
    <template #footer v-if="Footer">
      <slot name="footer">
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false" :loading="loading"
            >取消</el-button
          >
          <el-button type="primary" @click="submit" :loading="loading">
            确定
          </el-button>
        </span>
      </slot>
    </template>
  </el-dialog>
</template>
